package principal;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;
import objetsRadar.Traitement;
import visualisationRadar.VisualisationRadar;
import modelesObjet.ModelePiloteRadar;
import modelesObjet.ModelePluviometre;

/**
 * @author laurent
 * 
 */
public class PiloteRadar implements ModelePiloteRadar {

	private PiloteRadar() {
		imageRadar = null;
		Date date = Calendar.getInstance().getTime() ;
		System.out.println(FileFactory.dateToFormatHumain(date));
		
	}

	@Override
	public boolean chargeImage(File file) {
		if (!file.exists()) {
			System.err.println("Fichier " + file + " absent.");
			return false;
		}
		int type = FileFactory.getTypeFromFile(file);
		if (type == 0) {
			System.out.println("Fichier " + file.getName() + " non supporté.");
			return true;
		}
		ListeDonnees listeDonnees = ListeDonnees.getListeDonnees(file, type);
		if (listeDonnees == null)
			return true;
		imageRadar = new ImageRadar(file, listeDonnees, type);
		return true;

	}

	public static final PiloteRadar getInstance() {
		return instance;
	}

	@Override
	public boolean deplacerImage(int i) {
		if (imageRadar != null
				&& (imageRadar.getType() == VisualisationRadar.RR || imageRadar
						.getType() == VisualisationRadar.QUALITE))
			return imageRadar.deplace(i);
		else
			return true;
	}

	@Override
	public boolean switchQualiteRR() {
//		System.out.println("Switch qualité / RR");
		if (imageRadar == null)
			return true;
		File fichierACharger = null;
		if (imageRadar.getType() == VisualisationRadar.RR) {
			fichierACharger = FileFactory.getFileFrom(imageRadar.getRadar(),
					imageRadar.getDate(), VisualisationRadar.QUALITE);
		} else if (imageRadar.getType() == VisualisationRadar.QUALITE) {
			fichierACharger = FileFactory.getFileFrom(imageRadar.getRadar(),
					imageRadar.getDate(), VisualisationRadar.RR);
			/*
			 * Pour les cumuls, si le fichier à charger n'existe pas, on tente
			 * de le créer
			 */
		} else if (imageRadar.getType() == VisualisationRadar.RRcumul) {
			fichierACharger = FileFactory.getFileFrom(imageRadar.getRadar(),
					imageRadar.getDateDebut(), imageRadar.getDate(),
					VisualisationRadar.QUALITEcumul);
			if (!fichierACharger.exists()) {
				if (!creeFichierCumul(imageRadar.getRadar(),
						imageRadar.getDateDebut(), imageRadar.getDate(),
						VisualisationRadar.QUALITEcumul))
					return false;
			}
		} else if (imageRadar.getType() == VisualisationRadar.QUALITEcumul) {
			fichierACharger = FileFactory.getFileFrom(imageRadar.getRadar(),
					imageRadar.getDateDebut(), imageRadar.getDate(),
					VisualisationRadar.RRcumul);
			if (!fichierACharger.exists()) {
				if (!creeFichierCumul(imageRadar.getRadar(),
						imageRadar.getDateDebut(), imageRadar.getDate(),
						VisualisationRadar.RRcumul))
					return false;
			}

		}
		return chargeImage(fichierACharger);
	}

	@Override
	public ImageRadar getImageRadar() {
		return imageRadar;
	}

	@Override
	public boolean cumulVersLame() {
		int type = imageRadar.getType() == VisualisationRadar.RRcumul ? VisualisationRadar.RR
				: VisualisationRadar.QUALITE;

		File file = FileFactory.getFileFrom(imageRadar.getRadar(),
				imageRadar.getDate(), type);
		return chargeImage(file);
	}

	@Override
	public boolean lameVersCumul(int profondeur) {
//		System.out.println("Lame vers cumul");
		Date dateFin = imageRadar.getDate();
		Date dateDebut = FileFactory.changeDate(dateFin, Calendar.MINUTE,
				-profondeur);
		String radar = imageRadar.getRadar();
		int typeCumul = imageRadar.getType() == VisualisationRadar.RR ? VisualisationRadar.RRcumul
				: VisualisationRadar.QUALITEcumul;
		File fichierCumul = FileFactory.getFileFrom(radar, dateDebut, dateFin,
				typeCumul);
		/*
		 * Création du fichier cumul s'il n'existe pas.
		 */
		if (!fichierCumul.exists()) {
			System.out.println("Le fichier cumul " + fichierCumul.getName()
					+ " n'existe pas.");
			if (!creeFichierCumul(radar, dateDebut, dateFin, typeCumul)) {
				return false;
			}
		}

		return chargeImage(fichierCumul);
	}

	public boolean creeFichierCumul(String radar, Date dateDebut, Date dateFin,
			int typeCumul) {
		File fichierCumul;
		if (typeCumul == VisualisationRadar.RRcumul) {
			fichierCumul = FileFactory.getFileFrom(radar, dateDebut, dateFin,
					typeCumul);
		}
		/*
		 * Dans le cas de la qualité, il faut diviser les donnees du vecteur par
		 * le nombre de fichiers (cad faire la moyenne).
		 */
		else {
			fichierCumul = FileFactory.getFileFrom(radar, dateDebut, dateFin,
					typeCumul);
		}
		System.out
				.println("Création du fichier cumul "
						+ fichierCumul.getName()
						+ "....................... Patientez svp.");
		int type = typeCumul == VisualisationRadar.RRcumul ? VisualisationRadar.RR
				: VisualisationRadar.QUALITE;
		int profondeur = calculProfondeur(dateDebut, dateFin);
		/*
		 * Création de la liste des fichiers nécessaires au cumul
		 */
		File[] listeFiles = FileFactory.buildListeFiles(radar, dateFin, type,
				profondeur);
		/*
		 * Vérification de l'existence des fichiers
		 */
		if (!FileFactory.checkFiles(listeFiles)) {
			System.out.println("Impossible de créer le cumul.");
			return false;
		}
		/*
		 * Initialisation de vecDonnees avec le 1er fichier
		 */
		Vector<Double> vecDonnees;
		try {
			vecDonnees = Traitement.lireFichier(listeFiles[0].getName(), type);
			System.out.print("<-");
			int tailleTab = listeFiles.length - 1;
			int nbChar = 60 + fichierCumul.getName().length();
			int entier = 0;

			for (int i = 1; i < listeFiles.length; i++) {
				vecDonnees = ListeDonnees.additionneDonnees(vecDonnees,
						Traitement.lireFichier(listeFiles[i].getName(), type));
				int var = (int) (((double) i / (double) tailleTab) * (double) nbChar);
				if (var > entier) {
					if (tailleTab <= nbChar && i < listeFiles.length - 1) {
						for (int j = 0; j < nbChar / tailleTab; j++) {
							System.out.print("-");
						}
					} else if (tailleTab <= nbChar
							&& i == listeFiles.length - 1) {
						for (int j = 0; j < nbChar / tailleTab + nbChar
								% tailleTab; j++) {
							System.out.print("-");
						}
					} else {
						for (int j = 0; j < (double) nbChar
								/ (double) tailleTab; j++) {
							System.out.print("-");
						}
					}
					entier = var;
				}
			}
			System.out.println("->");
		} catch (IOException e) {
			e.printStackTrace();
			System.err.println("Impossible de créer le cumul : fichier "
					+ listeFiles[0].getName() + " est corrompu.");
			System.out.println();
			return false;
		}
		/*
		 * Dans le cas de la qualité, il faut diviser les donnees du vecteur par
		 * le nombre de fichiers (cad faire la moyenne).
		 */
		if (typeCumul == VisualisationRadar.QUALITEcumul) {
			vecDonnees = ListeDonnees.diviseDonnees(vecDonnees,
					listeFiles.length);
		}
		/*
		 * Ecriture du fichier
		 */
		try {
			Traitement.ecrireFichier(fichierCumul.getName(), typeCumul,
					vecDonnees);
		} catch (IOException e) {
			System.err.println("Impossible d'écrire le fichier cumul : "
					+ fichierCumul + ".");
			System.out.println();
			return false;
		}
		System.out.println();
		return true;
	}

	public int calculProfondeur(Date dateDebut, Date dateFin) {
		long diff = dateFin.getTime() - dateDebut.getTime();
		return (int) (diff / 60000);
	}

	@Override
	public void compareRadarPluvios(boolean biais, boolean eqm, int minQualite,
			int maxQualite) {

		if (maxQualite < minQualite) {
			System.out
					.println("La qualité max doit être inférieure à la qualité min.");
		} else {
			DecimalFormat df = new DecimalFormat("0.00");
			String radar = imageRadar.getRadar();
			Date dateDebut = imageRadar.getPluviometres().getDateDebut();
			Date dateFin = imageRadar.getPluviometres().getDateFin();
			File ficRRcumul = FileFactory.getFileFrom(radar, dateDebut,
					dateFin, VisualisationRadar.RRcumul);
			if (!ficRRcumul.exists()) {
				System.out.println("Fichier " + ficRRcumul
						+ " nécessaire au calcul.");
				creeFichierCumul(radar, dateDebut, dateFin,
						VisualisationRadar.RRcumul);
			}

			File ficQualiteCumul = FileFactory.getFileFrom(radar, dateDebut,
					dateFin, VisualisationRadar.QUALITEcumul);
			if (!ficQualiteCumul.exists()) {
				System.out.println("Fichier " + ficRRcumul
						+ " nécessaire au calcul.");
				creeFichierCumul(radar, dateDebut, dateFin,
						VisualisationRadar.QUALITEcumul);
			}
			Vector<Double> vecRR = ListeDonnees.getListeDonnees(ficRRcumul,
					VisualisationRadar.RRcumul).getVecteurDonnees();
			Vector<Double> vecQualite = ListeDonnees.getListeDonnees(
					ficQualiteCumul, VisualisationRadar.QUALITEcumul)
					.getVecteurDonnees();
			Vector<ModelePluviometre> vecPluvio = imageRadar.getPluviometres()
					.getVecteurPluviometres();
			Vector<Double> vecDiffPixPluvio = new Vector<Double>();
			int positionPluvio;
			for (int i = 0; i < vecPluvio.size(); i++) {
				positionPluvio = vecPluvio.get(i).getRadarY() * 512
						+ vecPluvio.get(i).getRadarX();
				if (vecQualite.get(positionPluvio) >= minQualite
						&& vecQualite.get(positionPluvio) <= maxQualite) {
					vecDiffPixPluvio.add(vecRR.get(positionPluvio)
							- vecPluvio.get(i).getRrPoste());
				}
			}
			System.out.println();
			String debut = FileFactory.dateToFormatHumain(dateDebut);
			String fin = FileFactory.dateToFormatHumain(dateFin);
			System.out.println("Pour la période du " + debut + " au " + fin
					+ " :");
			if (biais) {
				double sommeDiff = 0;
				for (Double diff : vecDiffPixPluvio) {
					sommeDiff += diff;
				}
				System.out.println("Biais = "
						+ df.format(sommeDiff / vecDiffPixPluvio.size()));
			}

			if (eqm) {
				double sommeDiffAuCarre = 0;
				for (Double diff : vecDiffPixPluvio) {
					sommeDiffAuCarre += Math.pow(diff, 2);
				}
				System.out.println("Eqm = "
						+ df.format(Math
								.sqrt((sommeDiffAuCarre / vecDiffPixPluvio
										.size()))));
			}
			System.out.println();
		}
	}

	private ImageRadar imageRadar;
	private static final PiloteRadar instance = new PiloteRadar();

}
